"""
Tabla de palabras(masterword) que almacena la cantidad de veces que se encontro
 esa palabra
en casa sample

(words)Tabla de palabras, por cada sample, (palabra-cantidad de ocurrencia)

(word)
Palabras: lista de cantidad de veces que aparecen en cada sample,
          porcentaje de aparicion,
          promedio de aparicion,

         ToDo
         07/04: Porcentaje de uso en cada sample, necesito la cantidad de palabras
                de cada sample, eso se puede obtener recorriendo la lista de samples(forma vertical)
                es una matriz donde posicionalmente se corresponde las palabras de cada sample,
                se recorre por ej. por cada palabra el elemento [0], si es mayor que cero
                esto indica que aparecio esa palabra en ese sample, se acumula
                esta ocurrencia y al final de la iteracion se tiene la cantidad
                de palabras que hubo en ese sample

"""

import os
from operator import itemgetter, attrgetter

class Word(object):
    """
    palabra
    """

    def __init__(self):
        self.word = ""
        self.list_sample = []


    def get_use_rate(self):
        """
        porcentaje de uso
        """
        cant = self.cant_samples
        use_rate = 0
        if cant != 0:
            sum = 0
            for sample in self.list_sample:
                if int(sample) > 0:
                    sum += 1
                use_rate = (float(sum) * 100) / float(cant)

        return use_rate

    use_rate = property(get_use_rate)

    def get_use_average(self):
        """
        Promedio de uso de palabras
        """
        cant = self.cant_samples
        sum = 0
        use_average = 0
        if cant != 0:
            use_average = float(self.sum_sample) / float(cant)

        return use_average

    use_average = property(get_use_average)

    def get_sum(self):
        """
        Suma total de samples
        """
        sum = 0
        for sample in self.list_sample:
            sum += int(sample)

        return sum

    sum_sample = property(get_sum)

    def get_cant_samples(self):
        return len(self.list_sample)

    cant_samples = property(get_cant_samples)

    def __rep__(self):
        return self.word, self.sum_sample




class TableWord:
    """
     Tabla que devuelve las palabras y la cantidad de ocurrencia de cada una.
    """
    def __init__(self,separator=" ", invalid_chars="", filter_word=[], \
                 remove_digit=True, remove_space=True, to_lower=True ):

        self.invalid_chars = invalid_chars
        self.separator = separator
        self.rmv_digit = remove_digit
        self.rmv_space = remove_space
        self.to_lower = to_lower
        self.table_word = {}
        self.filter_word = filter_word
        self.order_table_word = []

    def get_table_word(self,word_list):
        """
        Recibe una lista la recorre y devuelve por cada palabra la
        cantidad de veces que aparecieron
        """
        if len(self.table_word) > 0:
            cant_samples = self.cant_samples
        else:
            cant_samples = 0

        # relleno con ceros las palabras de la tabla
        for word in self.table_word:
            self.table_word[word].list_sample.append(0)

        for line in word_list:

            words = line.split(self.separator)

            for word in words:
                word = word.strip() #remove espacios en blanco
                if self.to_lower:
                    word = word.lower()
                # remove invalid chars
                for inv_char in self.invalid_chars:
                    word = word.replace(inv_char,"")
                if word in self.filter_word: #palabras filtradas
                    continue
                if self.rmv_digit:  # salteo digitos
                    if word.isdigit():
                        continue
                if self.rmv_space:  # salteo espacios
                    if word.isspace():
                        continue
                if word == "":  # salteo espacios
                    continue

                if word in self.table_word:
                    self.table_word[word].list_sample[-1] += 1
                else:
                    word_object = Word()
                    word_object.word = word
                    word_object.list_sample.extend([0] * cant_samples)
                    word_object.list_sample.append(1)
                    self.table_word[word] = word_object


    def get_sum_word(self):
        return len(self.table_word)

    def get_cant_samples(self):
        """
        Cuenta la cantidad de samples tiene procesado.
        saco el primer elemento y cuento la cantidad
        de samples
        """
        return len(self.table_word.items()[0][1])

    cant_samples = property(get_cant_samples)

    def get_order_word_ranking(self, reverse=False, *order_attr\
                             ):
            """
              Devuelve la lista ordenada de mayor a menor por defecto
            """
            #key = attrgetter(order_attr)

            #for word in self.master_table:
            self.order_table_word = sorted(self.table_word.itervalues(), \
                           key=attrgetter(*order_attr), reverse=reverse)

    def show_word_ranking(self, cant_words =-1, no_show_word=[]):
        """
        Muestra el ranking de palabras
        cant_word: cantidad de palabras a mostrar, por defecto todas -1
        no_show_word: palabras que no seran mostradas
        """
        cant = 0
        for word in self.order_table_word:

            if cant_words == cant:
                break
            if word.word in no_show_word:
                continue

            cant += 1
            print str(cant) + "   :  " + word.word + ": " + \
                  str(word.use_rate) + "(%): " + \
                  str(word.sum_sample) + "(Tot): " + \
                  str(word.use_average) + "(Prom):"





##    def get_cant_words_by_sample(self, sample_number):
##        """
##        Cuenta la cantidad de palabras que se usaron en cada sample
##        """
##        # Mapeo la posicion al indice correspondiente
##        sample_number = sample_number - 1
##        for word in sample




class MasterTableWord:
    """
    Base de datos que guarda los resultados de los samples procesados.
    """
    def __init__(self, input_file="masterword.txt", \
                       output_file="masterword.txt"):
        self.in_file = os.path.normpath(input_file)
        self.out_file = os.path.normpath(output_file)
        self.master_table = {}
        self.order_master_table = []  # lista ordenada de objetos

    def create_master_table(self, table_word={}):
        """
        Crea la tabla de resultados, de un archivo o  de una tabla de palabras
        """
        if len(table_word) > 0:
            if len(self.master_table) > 0:
                cant_samples = self.master_table.items()[0][1].cant_samples
            else:
                cant_samples = 0
            # relleno toda la tabla con ceros
            for word, word_object in self.master_table.iteritems():
                word_object.list_sample.append(0)
                self.master_table[word] = word_object

            for word, use_cant in table_word.iteritems():
                if word in self.master_table:
                    # agrego al ultimo objeto(un cero) el nuevo valor,
                    self.master_table[word].list_sample[-1] = use_cant
                else:
                    word_object = Word()
                    word_object.word = word
                    # agrego los ceros faltantes
                    word_object.list_sample.extend([0] * cant_samples)
                    word_object.list_sample.append(use_cant)
                    self.master_table[word] = word_object
        else:
            # Cargo la tabla desde un file
            if os.path.isfile(self.in_file):
                f = open(self.in_file,'r')
                for line in f.readlines():
                    line = line.split(":")
                    word = Word()
                    word.word = line[0]
                    word.list_sample.extend(line[1:])
                    self.master_table[word.word] = word
                f.close()

    def get_word_ranking(self, order_attr=['use_rate', 'sum_sample'], \
                         reverse=True):
        """
          Devuelve la lista ordenada de mayor a menor por defecto
        """
        for att in order_attr:
            key = attrgetter(att)

        #for word in self.master_table:
        self.order_master_table = sorted(self.master_table.itervalues(), \
                       key=key, \
                       reverse=reverse)

        for word in self.order_master_table:
            print word.word, str(word.use_rate), str(word.sum_sample)



FILE = "Friends - 10x08 - The One With The Late Thanksgiving.en.srt"
FILE2 = "Friends - 10x17 - The Last One (1).en.srt"

INVALIDACHAR = ":,.-?!</>\"[]"

f = open(FILE,'r')
##
table = TableWord(invalid_chars=INVALIDACHAR)
table.get_table_word(f.readlines())
f.close()

#print table.table_word["hey"].list_sample,table.table_word["hey"].cant_samples,table.get_sum_word()
table.get_order_word_ranking(False, 'word','sum_sample')
table.show_word_ranking(100)
##master = MasterTableWord()
##master.create_master_table(table.table_word)
##
##fx = open(FILE2,'r')
####
##table2 = TableWord(invalid_chars=INVALIDACHAR)
##table2.get_table_word(fx.readlines())
##fx.close()
##
##master.create_master_table(table2.table_word)
##
###print str(table.get_sum_word())
##print str(master.master_table["once"].list_sample)
##
##master.get_word_ranking(order_attr=['use_average'])




##p = Word()
##p.list_sample =[0,1,5,0,4,0,1]
##
##print str(p.use_average)



